local SINGLETON = nil function get_ui() SINGLETON = SINGLETON or pda_relations_tab() SINGLETON:Reset() return SINGLETON end class "pda_relations_tab" (CUIScriptWnd) function pda_relations_tab:__init() super() self.list = { "stalker", "dolg", "freedom", "csky", "ecolog", "killer", "army", "bandit", "monolith" } self.clr_red = utils_xml.get_color("red",true) -- GetARGB(255, 255, 1, 1) self.clr_green = utils_xml.get_color("green",true) -- GetARGB(255, 1, 255, 1) self.clr_yellow = utils_xml.get_color("yellow",true) -- GetARGB(255, 255, 255, 1) -- Tronex: use these factions if player is one of them local actor_comm = get_actor_true_community() if (actor_comm == "renegade") then self.list[9] = "renegade" elseif (actor_comm == "greh") then self.list[8] = "greh" elseif (actor_comm == "isg") then self.list[9] = "isg" end self.color_codes = { GetARGB(255,255,255,255), GetARGB(255,255,128,0), GetARGB(255,0,255,255), GetARGB(255,0,255,128), GetARGB(255,0,128,255), GetARGB(255,255,0,128), GetARGB(255,128,255,0), GetARGB(255,255,0,0), GetARGB(255,0,255,0), GetARGB(255,0,0,255), GetARGB(255,128,0,255), } self.companion_info = {} self.to_text = true self._tmr = time_global() self:InitControls() end function pda_relations_tab:__finalize() end function pda_relations_tab:InitControls() self:SetWndRect(Frect():set(0, 0, 1024, 768)) local xml = CScriptXmlInit() xml:ParseFile("pda_relations.xml") xml:InitFrame("frame",self) xml:InitStatic("center_background", self) self.tab = xml:InitStatic("tab", self) xml:InitStatic("tab:caption", self.tab) self.btn = xml:Init3tButton("btn_to_text", self) self:Register(self.btn, "btn") self:AddCallback("btn", ui_events.BUTTON_CLICKED, self.btn_to_text, self) -- Relation Matrix self.relations = {} local is_widescreen = true --utils_xml.is_widescreen() local x = is_widescreen and 40 or 55 local c_width = is_widescreen and 75 or 90 local c_height = 35 for i=1, #self.list do x = x + c_width local iobj = xml:InitTextWnd("tab:faction", self.tab) iobj:SetWndPos(vector2():set(x,65)) iobj:SetText(game.translate_string(self.list[i])) self.relations[i] = {} local y = 60 for k=0, #self.list do y = y + c_height if (i == 1) then local kobj = xml:InitTextWnd("tab:faction", self.tab) kobj:SetWndPos(vector2():set(x - c_width, y)) if k > 0 then kobj:SetText(game.translate_string(self.list[k])) else --kobj:SetText(game.translate_string("st_actor_generic_name")) kobj:SetText(game.translate_string("st_ui_goodwill_name")) end end self.relations[i][k] = xml:InitTextWnd("tab:cell",self.tab) self.relations[i][k]:SetWndPos(vector2():set(x,y)) end end -- Companion ListView xml:InitFrame("companion_frame",self) xml:InitStatic("companion_background",self) self.companion_listbox = xml:InitListBox("companion_wnd",self) self.companion_listbox:SetItemHeight(140) self.auto_chk = xml:InitCheck("auto_check",self) self.auto_chk:SetCheck(false) for row=1,4 do local row_form = ui_companion_row(self,row,xml) row_form:SetWndSize(vector2():set(740,140)) self.companion_listbox:AddExistingItem(row_form) end -- Hint Window self.hint_wnd = utils_ui.UIHint(self) end function pda_relations_tab:Update() CUIScriptWnd.Update(self) -- option to auto update values if self.auto_chk:GetCheck() then local tg = time_global() if self._tmr < tg then self._tmr = tg + 2000 self:autoupdate() end end if not (self.disabled) then for i=1, 24 do -- should be row*col from ui_companion_row if (self.companion_info[i].icon_wnd:IsShown()) then local pos = GetCursorPosition() local rect = Frect():set(0,0,0,0) self.companion_info[i].icon_wnd:GetAbsoluteRect(rect) if (utils_data.pos_in_rect(pos,rect)) then self.hint_wnd:Update(self.companion_info[i].hint) self.mouse_over_id = i return end end end end self.mouse_over_id = nil self.hint_wnd:Update() end function pda_relations_tab:autoupdate() local id_to_code = {} local clist = axr_companions.list_actor_squad_by_id() local sim = alife() for i=1,24 do -- should be row*col from ui_companion_row local se_obj = clist[i] and alife_object(clist[i]) if (se_obj and IsStalker(nil,se_obj:clsid()) and se_obj:alive()) then local full_name = se_obj:character_name() local name = string.gsub(full_name,"Junior","Jr.") name = string.gsub(name,"Senior","Sr.") name = string.gsub(name,"Master ","M") name = string.gsub(name,"Private","PVT") name = string.gsub(name,"Sergeant","SGT") name = string.gsub(name,"Lieutenant","LT") name = string.gsub(name,"Captain","CPT") local name = string.len(name) <= 22 and name or string.sub(name, 0, 19) .. "..." self.companion_info[i].id = se_obj.id local st = db.storage[se_obj.id] local npc = st and st.object local icon_name = npc and npc:character_icon() or se_obj:character_icon() icon_name = icon_name and icon_name ~= "" and icon_name or "ui\\ui_noise" self.companion_info[i].icon_wnd:InitTexture(icon_name) self.companion_info[i].icon_wnd:Show(true) self.companion_info[i].name_wnd:SetText(name) self.companion_info[i].comm_wnd:SetText(game.translate_string(se_obj:community())) self.companion_info[i].rank_wnd:SetText(game.translate_string("st_rank_"..ranks.get_se_obj_rank_name(se_obj)).." ("..se_obj:rank()..")") self.companion_info[i].dist_wnd:SetText(string.format(game.translate_string("st_distance_to")..": %.2f", se_obj.position:distance_to(db.actor:position()))) -- leader and relation status local squad = se_obj.group_id and se_obj.group_id ~= 65535 and alife_object(se_obj.group_id) if (squad and squad:commander_id() == se_obj.id) then self.companion_info[i].leader_wnd:Show(true) self.companion_info[i].leader_wnd:InitTexture("ui_minimap_squad_leader") else self.companion_info[i].leader_wnd:Show(true) self.companion_info[i].leader_wnd:InitTexture("ui_minimap_point") end -- Set color code if not (id_to_code[se_obj.group_id]) then local n = 1 for k,v in pairs(id_to_code) do n = n + 1 end id_to_code[se_obj.group_id] = self.color_codes[n] or self.color_codes[1] end self.companion_info[i].leader_wnd:SetTextureColor(id_to_code[se_obj.group_id]) -- health status if (npc) then local hp = math.floor(npc.health*100) self.companion_info[i].health_wnd:SetText(hp.."%") if (hp > 70) then self.companion_info[i].health_wnd:SetTextColor(GetARGB(200, 0, 255, 0)) elseif (hp < 30) then self.companion_info[i].health_wnd:SetTextColor(GetARGB(200, 255, 0, 0)) else self.companion_info[i].health_wnd:SetTextColor(GetARGB(200, 255, 255, 255)) end end -- Hint local s_move,s_combat,s_gather,s_loot,s_dist,s_stealth,s_arte,s_stalker,s_mutant,s_wounded,s_corpse,s_dismiss,s_tele local state_str = [[ %c[255,255,215,255]%c[default]%s \n \n%c[255,215,215,215]st_mm_pda_location:%c[default] %s \n \n%c[255,215,215,215]st_mm_pda_states:%c[default] \n %c[255,160,160,160]st_mm_pda_movement:%c[default] %s \n %c[255,160,160,160]st_mm_pda_combat:%c[default] %s \n %c[255,160,160,160]st_mm_pda_pickup_items:%c[default] %s \n %c[255,160,160,160]st_mm_pda_loot_corpses:%c[default] %s \n %c[255,160,160,160]st_mm_pda_keep_distance:%c[default] %s \n %c[255,160,160,160]st_mm_pda_stealth:%c[default] %s \n %c[255,160,160,160]st_mm_pda_dismissable:%c[default] %s \n %c[255,160,160,160]st_mm_pda_level_travel:%c[default] %s \n \n%c[255,215,215,215]st_mm_pda_statistics:%c[default] \n %c[255,160,160,160]st_mm_pda_stalkers_killed:%c[default] %s \n %c[255,160,160,160]st_mm_pda_mutants_killed:%c[default] %s \n %c[255,160,160,160]st_mm_pda_artes_found:%c[default] %s \n %c[255,160,160,160]st_mm_pda_wounded_helped:%c[default] %s \n %c[255,160,160,160]st_mm_pda_corpse_looted:%c[default] %s \n ]] if (sim:has_info(se_obj.id,"npcx_beh_wait")) then s_move = game.translate_string("st_set_companion_to_wait_state") elseif (sim:has_info(se_obj.id,"npcx_beh_patrol_mode")) then s_move = game.translate_string("st_set_companion_to_patrol_state") else s_move = game.translate_string("st_set_companion_to_follow_state") end if (sim:has_info(se_obj.id,"npcx_beh_ignore_actor_enemies") and sim:has_info(se_obj.id,"npcx_beh_ignore_combat")) then s_combat = game.translate_string("st_set_companion_to_ignore_combat_state") elseif (sim:has_info(se_obj.id,"npcx_beh_ignore_combat")) then s_combat = game.translate_string("st_set_companion_to_attack_only_actor_combat_enemy_state") else s_combat = game.translate_string("st_set_companion_to_attack_state") end local can_gather = sim:has_info(se_obj.id,"npcx_beh_gather_items") local can_loot = sim:has_info(se_obj.id,"npcx_beh_loot_corpses") s_gather = can_gather and game.translate_string("st_pda_mode_on") or game.translate_string("st_pda_mode_off") s_loot = can_loot and game.translate_string("st_pda_mode_on") or game.translate_string("st_pda_mode_off") if (npc) then -- If looting is set false in logic if (can_gather and st.gather_items and st.gather_items.gather_items_enabled and xr_logic.pick_section_from_condlist(db.actor, npc, st.gather_items.gather_items_enabled) == "false") then s_gather = game.translate_string("st_pda_mode_disabled") end if (can_loot and st.corpse_detection and st.corpse_detection.corpse_detection_enabled and xr_logic.pick_section_from_condlist(db.actor, npc, st.corpse_detection.corpse_detection_enabled) == "false") then s_loot = game.translate_string("st_pda_mode_disabled") end end s_dist = sim:has_info(se_obj.id,"npcx_beh_distance_far") and game.translate_string("st_pda_mode_dist_far") or game.translate_string("st_pda_mode_dist_near") s_stealth = sim:has_info(se_obj.id,"npcx_beh_substate_stealth") and game.translate_string("st_pda_mode_on") or game.translate_string("st_pda_mode_off") local m_data = alife_storage_manager.get_se_obj_state(se_obj) if (m_data) then s_stalker = m_data["killed_stalkers"] or 0 s_mutant = m_data["killed_monsters"] or 0 s_arte = m_data["artefacts_found"] or 0 s_wounded = m_data["wounded_helped"] or 0 s_corpse = m_data["corpse_looted"] or 0 end s_dismiss = se_load_var(se_obj.id,se_obj:name(),"companion_cannot_dismiss") and game.translate_string("st_pda_mode_false") or game.translate_string("st_pda_mode_true") s_tele = se_load_var(se_obj.id,se_obj:name(),"companion_cannot_teleport") and game.translate_string("st_pda_mode_disabled") or game.translate_string("st_pda_mode_enabled") local s_location = game.translate_string(sim:level_name(game_graph():vertex(se_obj.m_game_vertex_id):level_id())) for s in string.gmatch(state_str,"(st_mm_pda_[%w%d_]*)") do state_str = string.gsub(state_str,s,game.translate_string(s)) end state_str = strformat(state_str,full_name,s_location,s_move,s_combat,s_gather,s_loot,s_dist,s_stealth,s_dismiss,s_tele,s_stalker,s_mutant,s_arte,s_wounded,s_corpse) self.companion_info[i].hint = state_str else self.companion_info[i].id = nil self.companion_info[i].icon_wnd:Show(false) self.companion_info[i].leader_wnd:Show(false) self.companion_info[i].health_wnd:SetText("") self.companion_info[i].name_wnd:SetText("") self.companion_info[i].comm_wnd:SetText("") self.companion_info[i].rank_wnd:SetText("") self.companion_info[i].dist_wnd:SetText("") end end end function pda_relations_tab:Reset() for i=1, #self.list do for k=0, #self.list do local comm = self.list[k] or db.actor:character_community() local r_val = relation_registry.community_relation(comm, self.list[i]) --if first row then goodwill if(k == 0) then r_val = relation_registry.community_goodwill(self.list[i],AC_ID) if r_val >= 2000 then self.relations[i][k]:SetTextColor(self.clr_green) self.relations[i][k]:SetText(game.translate_string("st_ui_goodwill_5")) elseif r_val < 2000 and r_val >= 1500 then self.relations[i][k]:SetTextColor(self.clr_yellow) self.relations[i][k]:SetText(game.translate_string("st_ui_goodwill_4")) elseif r_val < 1500 and r_val >= 1000 then self.relations[i][k]:SetTextColor(self.clr_yellow) self.relations[i][k]:SetText(game.translate_string("st_ui_goodwill_3")) elseif r_val < 1000 and r_val >= 500 then self.relations[i][k]:SetTextColor(self.clr_yellow) self.relations[i][k]:SetText(game.translate_string("st_ui_goodwill_2")) else self.relations[i][k]:SetTextColor(self.clr_red) self.relations[i][k]:SetText(game.translate_string("st_ui_goodwill_1")) end else if r_val >= game_relations.FRIENDS then self.relations[i][k]:SetTextColor(self.clr_green) self.relations[i][k]:SetText(game.translate_string("st_goodwill_friendly")) elseif r_val <= game_relations.ENEMIES then self.relations[i][k]:SetTextColor(self.clr_red) self.relations[i][k]:SetText(game.translate_string("st_goodwill_enemy")) else self.relations[i][k]:SetTextColor(self.clr_yellow) self.relations[i][k]:SetText(game.translate_string("st_goodwill_indifferent")) end end if not (self.to_text) then self.relations[i][k]:SetText(tostring(r_val)) end end end self:autoupdate() end function pda_relations_tab:btn_to_text() self.to_text = not self.to_text if self.to_text then self.btn:TextControl():SetText(game.translate_string("pda_table_value_off")) else self.btn:TextControl():SetText(game.translate_string("pda_table_value_on")) end self:Reset() end --------------------------------------------------------------------------------------------------- -- --------------------------------------------------------------------------------------------------- class "ui_companion_row" (CUIListBoxItem) function ui_companion_row:__init(owner,row,xml) super(owner,row,xml) self:GetTextItem():SetText("") local is_widescreen = true --utils_xml.is_widescreen() local x = is_widescreen and 20 or 35 local y = 0 for i=1,6 do local n = i+(6*(row-1)) owner.companion_info[n] = { ["id"] = nil, ["icon_wnd"] = self:AddIconField(1), ["leader_wnd"] = self:AddIconField(1), ["name_wnd"] = self:AddTextField("",1), ["comm_wnd"] = self:AddTextField("",1), ["rank_wnd"] = self:AddTextField("",1), ["health_wnd"] = self:AddTextField("",1), ["dist_wnd"] = self:AddTextField("",1), ["hint"] = "" } owner.companion_info[n].icon_wnd:InitTexture("ui\\ui_noise") owner.companion_info[n].icon_wnd:SetStretchTexture(true) owner.companion_info[n].icon_wnd:SetWndSize(vector2():set(64,64)) owner.companion_info[n].icon_wnd:SetWndPos(vector2():set(x,y)) owner.companion_info[n].leader_wnd:InitTexture("ui_minimap_squad_leader") owner.companion_info[n].leader_wnd:SetStretchTexture(true) owner.companion_info[n].leader_wnd:SetWndSize(vector2():set(is_widescreen and 8 or 10,10)) owner.companion_info[n].leader_wnd:SetWndPos(vector2():set(x,y)) owner.companion_info[n].name_wnd:SetFont(GetFontLetterica18Russian()) owner.companion_info[n].name_wnd:SetWndSize(vector2():set(120,22)) owner.companion_info[n].name_wnd:SetWndPos(vector2():set(x,y+65)) owner.companion_info[n].comm_wnd:SetFont(GetFontLetterica16Russian()) owner.companion_info[n].comm_wnd:SetWndSize(vector2():set(120,20)) owner.companion_info[n].comm_wnd:SetWndPos(vector2():set(x,y+90)) owner.companion_info[n].rank_wnd:SetFont(GetFontLetterica16Russian()) owner.companion_info[n].rank_wnd:SetWndSize(vector2():set(120,20)) owner.companion_info[n].rank_wnd:SetWndPos(vector2():set(x,y+105)) owner.companion_info[n].health_wnd:SetFont(GetFontSmall()) owner.companion_info[n].health_wnd:SetWndSize(vector2():set(50,10)) owner.companion_info[n].health_wnd:SetWndPos(vector2():set(x+50,y+55)) owner.companion_info[n].dist_wnd:SetFont(GetFontLetterica16Russian()) owner.companion_info[n].dist_wnd:SetWndSize(vector2():set(120,20)) owner.companion_info[n].dist_wnd:SetWndPos(vector2():set(x,y+120)) x = x + (is_widescreen and 125 or 155) end end